package com.hero.take.util;

import cn.hutool.core.date.DateUtil;
import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

public class DateHelpper {

    public static Date getYYYYMMDD(Date dt) {
        SimpleDateFormat spdt = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        try {
            return spdt.parse(cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" + cal.get(Calendar.DAY_OF_MONTH));
        } catch (ParseException e) {
            return cal.getTime();
        }
    }

    public static Date getDate(String dateStr, String f) {
        try {
            return new SimpleDateFormat(f).parse(dateStr);
        } catch (Exception e) {
            return null;
        }
    }

    public static Date getYYYYMMDD() {
        return getYYYYMMDD(new Date());
    }

    public static boolean isValidDate(String date) {
        if (date == null) {
            return false;
        }
        if (StringUtils.isEmpty(date)) {
            return false;
        }
        if ("0".equals(date)) {
            return false;
        }
        return true;
    }

    public static String dateStr2(String date, String f) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat(f);
        String str = format.format(getDate(Long.parseLong(date)));

        return str;
    }

    public static String dateStr(Long date, String f) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat(f);
        String str = format.format(getDate(date));
        return str;
    }

    public static String dateStr2(Integer date, String f) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat(f);
        String str = format.format(getDate(date));
        return str;
    }

    public static String dateStr(Date dt, String f) {
        if (dt == null) return "";
        if (StringUtils.isBlank(f)) return dt.toString();
        SimpleDateFormat spdt = new SimpleDateFormat(f);
        return spdt.format(dt);
    }

    public static String dateStr(Date dt) {
        return dateStr(dt, DateTimeFormat.yyyyMMddHHmmss);
    }

    public static long getDateLong(String datestr, String f) throws ParseException {

        SimpleDateFormat sdf = new SimpleDateFormat(f);
        Date date;

        date = sdf.parse(datestr);
        return DateHelpper.getTimeLong(date);
    }

    /**
     * 将秒转换成时间
     *
     * @param times
     * @return
     */
    public static Date getDate(long times) {
        return new Date(times * 1000);
    }

    public static Date getDate(int year, int month, int day) {
        Calendar cal = Calendar.getInstance();
        cal.clear();
        cal.set(Calendar.YEAR, year);             //设置年份
        cal.set(Calendar.MONTH, month - 1);       //设置月份，因为月份从0开始，所以用month - 1
        cal.set(Calendar.DAY_OF_MONTH, day);
        return cal.getTime();
    }


    public static long getTime(Date date) {
        return date.getTime() / 1000;
    }

    public static int getHour(Date d) {
        if (d == null) return 0;
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        return cal.get(Calendar.HOUR_OF_DAY);
    }

    public static int getMinute(Date d) {
        if (d == null) return 0;
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        return cal.get(Calendar.MINUTE);
    }

    public static int getSecond(Date d) {
        if (d == null) return 0;
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        return cal.get(Calendar.SECOND);
    }

    public static int getDay(Date d) {
        if (d == null) return 0;
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        return cal.get(Calendar.DAY_OF_MONTH);
    }

    public static int getMonthOfDate(Date d) {
        if (d == null) return 0;
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        //月份从0开始，所以加1
        return cal.get(Calendar.MONTH) + 1;
    }

    public static String getYearMonthStrOfDate(Date d) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        int month = cal.get(Calendar.MONTH) + 1;
        return cal.get(Calendar.YEAR) + (month > 9 ? "" : "0") + month;
    }

    public static int getYearOfDate(Date d) {
        if (d == null) return 0;
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        return cal.get(Calendar.YEAR);
    }

    public static Date rollMinute(Date d, int minute) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        cal.add(Calendar.MINUTE, minute);
        return cal.getTime();
    }

    public static Date rollDay(Date d, int day) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        cal.add(Calendar.DAY_OF_MONTH, day);
        return cal.getTime();
    }

    public static Date rollHour(Date d, int hours) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        cal.add(Calendar.HOUR_OF_DAY, hours);
        return cal.getTime();
    }

    public static Date rollMon(Date d, int mon) {

        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        cal.add(Calendar.MONTH, mon);
        return cal.getTime();
    }

    public static Date rollYear(Date d, int year) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        cal.add(Calendar.YEAR, year);
        return cal.getTime();
    }

    public static Date rollDate(Date d, int year, int mon, int day) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        cal.add(Calendar.YEAR, year);
        cal.add(Calendar.MONTH, mon);
        cal.add(Calendar.DAY_OF_MONTH, day);
        return cal.getTime();
    }


    /**
     * 获取当前时间的秒数字符串
     *
     * @return
     */
    public static Long getNowTimeStr() {
        return System.currentTimeMillis() / 1000;
    }

    public static Integer getNowTime() {
        return Math.toIntExact(getNowTimeStr());
    }

    public static String getTimeStr(Date time) {
        long date = time.getTime();
        String str = Long.toString(date / 1000);
        return str;
    }

    public static long getTimeLong(Date time) {
        long date = time.getTime();
        long longdate = date / 1000;
        return longdate;
    }

    /**
     * 判断时间1是否大于时间2
     *
     * @param time1
     * @param time2
     * @return
     */
    public static boolean compareTime(Long time1, Long time2) {
        boolean flag = true;
        if (time1 <= time2) {
            flag = false;
        }
        return flag;
    }

    public static long rollMonth(long addtime, int time_limit) {
        Date t = DateHelpper.rollDate(DateHelpper.getDate(addtime), 0, time_limit, 0);
        return t.getTime() / 1000;
    }

    public static long rollDay(long addtime, int time_limit_day) {
        Date t = DateHelpper.rollDate(DateHelpper.getDate(addtime), 0, 0, time_limit_day);
        return t.getTime() / 1000;
    }

    public static Date getIntegralTime() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    public static Date getLastIntegralTime() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    public static Date getLastSecIntegralTime(Date d) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(d.getTime());
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * @param nowTime   当前时间
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     * @author sunran   判断当前时间在时间区间内
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

    public static String getLastTime(String dateStr, int addYear, int addMonth, int addDate) throws Exception {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date sourceDate = sdf.parse(dateStr);
            Calendar cal = Calendar.getInstance();
            cal.setTime(sourceDate);
            cal.add(Calendar.YEAR, addYear);
            cal.add(Calendar.MONTH, addMonth);
            cal.add(Calendar.DATE, addDate);

            SimpleDateFormat returnSdf = new SimpleDateFormat("yyyy-MM-dd");
            String dateTmp = returnSdf.format(cal.getTime());
            Date returnDate = returnSdf.parse(dateTmp);
            return dateTmp;
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception(e.getMessage());
        }
    }

    public static long getTime(String format) {
        long t = 0;
        if (StringUtils.isBlank(format)) return t;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date;
        try {
            date = sdf.parse(format);
            t = date.getTime() / 1000;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return t;
    }

    public static String getWeekOfDate(Date date) {
        if (date == null)
            return null;
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return weekDays[w];
    }

    public static int getDayOfWeek(Date date) {
        if (date == null)
            return -1;
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w <= 0)
            w = 7;
        return w;
    }

    public static String getDayStrOfWeek(Object date) {
        if (date == null)
            return null;
        Date d = null;
        if(date instanceof Date){
            d = (Date) date;
        }else if(date instanceof String){
            d = getDate(date.toString(),"yyyy-MM-dd");
        }else if(date instanceof LocalDateTime){
            LocalDateTime d1 = (LocalDateTime) date;
            d = new Date(LocalDateUtils.toTimes(d1));
        }else if(date instanceof LocalDate){
            d = getDate(date.toString(),"yyyy-MM-dd");
        }
        if(d == null) return null;
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w <= 0)
            w = 7;
        switch (w){
            case 1:return "星期一";
            case 2:return "星期二";
            case 3:return "星期三";
            case 4:return "星期四";
            case 5:return "星期五";
            case 6:return "星期六";
            case 7:return "星期日";
        }
        return null;
    }


    /**
     * 把时间戳转换为：时分秒
     *
     * @param millisecond ：毫秒，传入单位为毫秒
     */
    public static String getTimeString(long millisecond) {
        if (millisecond < 1000) {
            return "0" + "秒";
        }
        long time = millisecond / 1000;
        if (time < 60) {
            return time + "秒";
        } else {
            long minute = time / 60;
            long second = time - minute * 60;
            return minute + "分" + second + "秒";
        }
//        long second = millisecond / 1000;
//        long seconds = second % 60;
//        long minutes = second / 60;
//        long hours = 0;
//        if (minutes >= 60) {
//            hours = minutes / 60;
//            minutes = minutes % 60;
//        }
//        String timeString = "";
//        String secondString = "";
//        String minuteString = "";
//        String hourString = "";
//        if (seconds < 10) {
//            secondString = "0" + seconds + "秒";
//        } else {
//            secondString = seconds + "秒";
//        }
//        if (minutes < 10 && hours < 1) {
//            minuteString = minutes + "分";
//        } else if (minutes < 10){
//            minuteString =  "0" + minutes + "分";
//        } else {
//            minuteString = minutes + "分";
//        }
//        if (hours < 10) {
//            hourString = hours + "时";
//        } else {
//            hourString = hours + "" + "时";
//        }
//        if (hours != 0) {
//            timeString = hourString + minuteString + secondString;
//        } else {
//            timeString = minuteString + secondString;
//        }

    }

    /**
     * 今年开始
     *
     * @return
     */
    public static Date beginOfYear() {
        return DateUtil.beginOfYear(new Date()).toCalendar().getTime();
    }

    /**
     * 今年开始
     *
     * @return
     */
    public static Date endOfYear() {
        return DateUtil.endOfYear(new Date()).toCalendar().getTime();
    }

    /**
     * 去年开始
     *
     * @return
     */
    public static Date beginOfLastYear() {
        return DateUtil.beginOfYear(rollYear(new Date(), -1)).toCalendar().getTime();
    }

    /**
     * 去年结束
     *
     * @return
     */
    public static Date endOfLastYear() {
        return DateUtil.endOfYear(rollYear(new Date(), -1)).toCalendar().getTime();
    }


    /**
     * 获取两个日期之间所有的日期 精确到月 yyyy-MM
     * @param dateStart
     * @param dateEnd
     * @return
     */
    public static List<String> getAllMonthBetweenDate(String dateStart, String dateEnd) {
        List<String> dateList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");

        try {
            //将String类型转为Date类型
            Date dateOne = sdf.parse(dateStart);
            Date dateTwo = sdf.parse(dateEnd);
            //设置日历时间
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(dateTwo);
            //将最后一天放入集合
            dateList.add(sdf.format(dateTwo));
            //将结束的日历时间循环减去 1天 并存入集合，当日历时间等于开始时间就结束循环
            while (calendar.getTime().after(dateOne)) {
                calendar.add(Calendar.MONTH, -1);
                dateList.add(sdf.format(calendar.getTime()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Collections.reverse(dateList);
        return dateList;
    }

    /**
     * 获取指定周的开始时间
     * @return
     */
    public static Date getStartTimeOfCurrentWeek(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        setMinTimeOfDay(calendar);
        return calendar.getTime();
    }

    /**
     * 获取指定月的结束时间
     * @return
     */
    public static Date getEndTimeOfCurrentWeek(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        setMaxTimeOfDay(calendar);
        return calendar.getTime();
    }

    /**
     * 获取指定月的开始时间
     * @return
     */
    public static Date getStartTimeOfCurrentMonth(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        calendar.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),1);
        setMinTimeOfDay(calendar);
        return calendar.getTime();
    }

    /**
     * 获取指定月的结束时间
     * @return
     */
    public static Date getEndTimeOfCurrentMonth(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        int maxMonthDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        calendar.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),maxMonthDay);
        setMaxTimeOfDay(calendar);
        return calendar.getTime();
    }

    /**
     * 获取指定年的开始时间 注意月份要减1
     * @return
     */
    public static Date getStartTimeOfCurrentYear(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        calendar.set(calendar.get(Calendar.YEAR),0,1);
        setMinTimeOfDay(calendar);
        return calendar.getTime();
    }

    /**
     * 获取指定年的结束时间 注意月份要减1
     * @return
     */
    public static Date getEndTimeOfCurrentYear(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        calendar.set(calendar.get(Calendar.YEAR),11,31);
        setMaxTimeOfDay(calendar);
        return calendar.getTime();
    }

    /**
     * 设置当天的开始时间
     * @param calendar
     */
    private static void setMinTimeOfDay(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.MILLISECOND, 0);
    }

    /**
     * 设置当天的结束时间
     * @param calendar
     */
    private static void setMaxTimeOfDay(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.MILLISECOND, 999);
    }


}
